[id].vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <!-- @format -->
  2. <script lang="ts" setup>
  3. import { ArrowRight } from '@element-plus/icons-vue'
  4. import { useData } from './useData'
  5. import { getParentsById } from '~/utils/object'
  6. import { ConstKeys } from '~/enums/const-enums'
  7. const route = useRoute()
  8. useHead({
  9. title: `Wholesale ${route.query.label} for Your Store | EJET Selection`,
  10. meta: [
  11. {
  12. name: 'description',
  13. content: `Browse EJET Selection's product categories, including Home Decor, Kitchen Appliance, Beauty, and Pets. Find high-quality wholesale products to meet your retail needs.`,
  14. },
  15. {
  16. property: 'og:title',
  17. content: `Wholesale ${route.query.label} for Your Store | EJET Selection`,
  18. },
  19. {
  20. property: 'og:description',
  21. content:
  22. `Browse EJET Selection's product categories, including Home Decor, Kitchen Appliance, Beauty, and Pets. Find high-quality wholesale products to meet your retail needs.`,
  23. },
  24. {
  25. property: 'og:type',
  26. content: 'website',
  27. },
  28. {
  29. property: 'twitter:title',
  30. content: `Wholesale ${route.query.label} for Your Store | EJET Selection`,
  31. },
  32. {
  33. property: 'twitter:description',
  34. content:
  35. `Browse EJET Selection's product categories, including Home Decor, Kitchen Appliance, Beauty, and Pets. Find high-quality wholesale products to meet your retail needs.`,
  36. },
  37. {
  38. property: 'twitter:card',
  39. content: 'summary_large_image',
  40. },
  41. ],
  42. link: [
  43. {
  44. rel: 'canonical',
  45. href: `${ConstKeys.DOMAINPRO}/categories/${route.query.key}`,
  46. },
  47. ],
  48. })
  49. const {
  50. categories,
  51. goodsList,
  52. page_size,
  53. top_data,
  54. selectedCategory,
  55. currentPage,
  56. getCategories,
  57. changePage,
  58. form,
  59. total,
  60. handleSelectedCategory,
  61. handleOrderBy,
  62. handleSelectedFilters,
  63. } = useData()
  64. const crumbs = ref<any>([{ name: 'Home', url: '/' }])
  65. const options = [{
  66. label: 'Sort by MOQ',
  67. value: 'smoq',
  68. }, {
  69. label: 'Sort by Price',
  70. value: 'sprice',
  71. }, {
  72. label: 'Sort by Date',
  73. value: 'sdate',
  74. }]
  75. watch(
  76. () => route.query.secondKey,
  77. (value: any) => {
  78. if (categories.value.length)
  79. handleSelectedCategory(value)
  80. },
  81. {
  82. immediate: true,
  83. },
  84. )
  85. watch(
  86. () => selectedCategory.value,
  87. async (value: any) => {
  88. if (value)
  89. handlerCrumb(value)
  90. },
  91. )
  92. function handlerCrumb(value: any) {
  93. const filterArr = getParentsById(categories.value, value)
  94. const baseCrumb = [{ name: 'Home', url: '/' }, { name: top_data.value.title, url: '' }]
  95. if (filterArr.length > 0) {
  96. const arr: any = []
  97. filterArr.forEach((ele: any) => {
  98. arr.unshift({
  99. name: ele.title,
  100. url: '',
  101. })
  102. })
  103. crumbs.value = [...baseCrumb, ...arr]
  104. }
  105. else {
  106. crumbs.value = [...baseCrumb]
  107. }
  108. }
  109. async function getAllData() {
  110. await getCategories()
  111. const route = useRoute()
  112. const secondLevel = route.query.secondKey
  113. if (secondLevel)
  114. handleSelectedCategory(secondLevel)
  115. else
  116. handleSelectedCategory(top_data.value.key)
  117. if (route.params.id && secondLevel)
  118. handlerCrumb(secondLevel)
  119. else crumbs.value.push({ name: top_data.value?.title, url: '' })
  120. }
  121. getAllData()
  122. </script>
  123. <template>
  124. <div class="">
  125. <div class="mb-42px">
  126. <div class="relative">
  127. <business-category-headerBanner :slug="route.params.id" />
  128. </div>
  129. <div class="w-1400px mx-auto pt-40px pb-20px">
  130. <div class="fw-300">
  131. <el-breadcrumb :separator-icon="ArrowRight">
  132. <el-breadcrumb-item
  133. v-for="(item, index) in crumbs" :key="index"
  134. :to="!!item.url ? { path: item.url } : null"
  135. >
  136. {{ item.name }}
  137. </el-breadcrumb-item>
  138. </el-breadcrumb>
  139. </div>
  140. </div>
  141. </div>
  142. <div class="w-1400px mx-auto mb-120px">
  143. <el-row class="row-bg">
  144. <el-col :span="5">
  145. <business-category-left-slider v-model:selectedValue="selectedCategory" :top-level="top_data" :list="categories" @on-select="handleSelectedCategory" />
  146. <div class="h-1px bg-#DCDFE6 my-40px" />
  147. <business-category-left-filters @on-select-filters="handleSelectedFilters" />
  148. </el-col>
  149. <el-col :span="1" />
  150. <el-col :span="18">
  151. <div class="flex justify-end mb-32px">
  152. <el-select v-model="form.orderby" placeholder="Select Sorting Method " :clearable="true" size="large" style="width: 240px" @change="handleOrderBy">
  153. <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
  154. </el-select>
  155. </div>
  156. <div v-if="goodsList.length">
  157. <div class="grid grid-gap-x-65px grid-gap-y-65px grid-cols-3">
  158. <div v-for="item in goodsList" :key="item.id">
  159. <common-goods-item :item="item" />
  160. </div>
  161. </div>
  162. <div class="mt-60px flex justify-center">
  163. <el-pagination
  164. v-model:current-page="currentPage" :page-size="page_size" :pager-count="10"
  165. layout="prev, pager, next" :total="total" @change="changePage"
  166. />
  167. </div>
  168. </div>
  169. <common-empty v-else class="mt-200px" title="No brand found ~" />
  170. </el-col>
  171. </el-row>
  172. </div>
  173. <business-category-swiperBrands />
  174. <business-category-exploreProduct />
  175. <AppFooter />
  176. </div>
  177. </template>
  178. <style lang="less" scoped></style>